package cn.loger.jenkins;

import hudson.Extension;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.TransientProjectActionFactory;
import hudson.model.Hudson;
import hudson.security.Permission;
import hudson.util.HttpResponses;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.interceptor.RequirePOST;

import javax.servlet.ServletException;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;

public class DirectoryDeleteAction implements Action {
    private final AbstractProject<?, ?> project;
    private final String filePath;

    public DirectoryDeleteAction(AbstractProject<?, ?> project, String filePath) {
        this.project = project;
        this.filePath = filePath;
    }

    @Override
    public String getIconFileName() {
        // 只有管理员和有删除权限的用户才能看到删除按钮
        if (Jenkins.get().hasPermission(Permission.DELETE)) {
            return "symbol-trash";
        }
        return null;
    }

    @Override
    public String getDisplayName() {
        return "Delete";
    }

    @Override
    public String getUrlName() {
        return "deleteDir";
    }

    @RequirePOST
    public void doDelete(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
        System.out.println("doDelete");
        // 检查权限
//        Jenkins.get().checkPermission(Permission.DELETE);

        // 获取要删除的文件/文件夹
        File fileToDelete = new File(project.getWorkspace().getRemote() + File.separator + filePath);

        // 验证文件是否存在且属于当前项目的工作空间
        if (!fileToDelete.exists() || !isFileInWorkspace(fileToDelete, project.getWorkspace().getRemote())) {
            rsp.sendError(404, "文件或文件夹不存在");
            return;
        }

        // 执行删除操作
        boolean deleted = deleteFileOrDirectory(fileToDelete);

        if (deleted) {
            // 删除成功
            rsp.setStatus(200);
            rsp.getWriter().write("删除成功");
        } else {
            // 删除失败
            rsp.sendError(500, "删除失败");
        }
    }

    // 递归删除文件和文件夹
    private boolean deleteFileOrDirectory(File file) {
        if (file.isDirectory()) {
            File[] children = file.listFiles();
            if (children != null) {
                for (File child : children) {
                    if (!deleteFileOrDirectory(child)) {
                        return false;
                    }
                }
            }
        }
        return file.delete();
    }

    // 验证文件是否在工作空间内，防止路径遍历攻击
    private boolean isFileInWorkspace(File file, String workspacePath) throws IOException {
        String canonicalFilePath = file.getCanonicalPath();
        String canonicalWorkspacePath = new File(workspacePath).getCanonicalPath();
        return canonicalFilePath.startsWith(canonicalWorkspacePath);
    }

    @Extension
    public static class Factory extends TransientProjectActionFactory {
        @Override
        public Collection<? extends Action> createFor(AbstractProject target) {
            return Collections.singletonList(new DirectoryDeleteAction(target, ""));
        }
    }
}
